/**
 * 这是带标题的小图标
 */

import EditorExecutor from '@/executor/EditorExecutor'
import GraphUtil from '@/util/GraphUtil'
import { Tooltip } from 'antd'
import { mxCell, mxGraph } from 'mxgraph'
import { DOMElement, useEffect, useRef, useState } from 'react'

interface IShape {
  style?: string
  isEdge?: boolean
  width: number
  height: number
  name: string
  value: string
  label: string
  attrs?: { [key: string]: number | string }
}
interface IThumbProps {
  graph: mxGraph
  shape: IShape
}

const thumbBorder = 1
const thumbWdith = 32
const thumbHeight = 31

// 自定义图形类型, 自定义的图形会有额外的属性设置
const customShapeNames = ['HDataPoint', 'HImg']

/**
 * 生成mxCell,返回一个数组
 * @param shape
 * @returns
 */
function createCells(shape: IShape): mxCell[] {
  const { style = '', isEdge, width, height, value, name } = shape
  let cell: mxCell
  if (isEdge) {
    cell = GraphUtil.createEdgeTemplateEntry(style, width, height)
  } else {
    cell = GraphUtil.createVertexTemplateEntry(style, width, height, value)
  }
  // 对自定义图形的处理
  if (customShapeNames.includes(name)) {
    const oldV = cell.getValue()
    //@ts-ignore
    if (!mxUtils.isNode(oldV)) {
      const doc = mxUtils.createXmlDocument()
      const obj = doc.createElement('object')
      obj.setAttribute('label', oldV || '')

      obj.setAttribute('type', name)
      const { attrs } = shape
      attrs &&
        Object.keys(attrs).forEach((attr) => {
          obj.setAttribute(attr, attrs[attr].toString())
        })
      cell.setValue(obj)
    }
  }
  return [cell]
}

/**
 * 根据cell,返回svg 格式字符串
 * @param graph
 * @param cells
 * @returns
 */
function getSVGNode(graph: mxGraph, cells: mxCell[]): string {
  // 缩略图合适的比例
  graph.view.scaleAndTranslate(1, 0, 0)
  graph.addCells(cells)
  const bounds = graph.getGraphBounds()
  // graph.view.scaleAndTranslate(0.8, 20, 0)
  const s =
    Math.floor(
      Math.min(
        (thumbWdith - 2 * thumbBorder) / bounds.width,
        (thumbHeight - 2 * thumbBorder) / bounds.height
      ) * 100
    ) / 100
  graph.view.scaleAndTranslate(
    s,
    Math.floor((thumbWdith - bounds.width * s) / 2 / s - bounds.x),
    Math.floor((thumbHeight - bounds.height * s) / 2 / s - bounds.y)
  )
  let node: any
  if (
    graph.dialect == mxConstants.DIALECT_SVG &&
    !mxClient.NO_FO &&
    graph.view.getCanvas().ownerSVGElement != null
  ) {
    node = graph?.view?.getCanvas()?.ownerSVGElement?.cloneNode(true)
  }
  if (node) {
    node.style.width = thumbWdith + 'px'
    node.style.height = thumbHeight + 'px'
  }

  graph.model.clear()
  return node.outerHTML
}

export default function Thumb(props: IThumbProps) {
  const { graph, shape } = props
  const [html, setHtml] = useState('')
  // 当前图形的cell
  const cell = useRef<mxCell>()
  // 当前节点的引用
  const dom = useRef<HTMLAnchorElement>(null)

  // 加载时初始化
  useEffect(() => {
    const cells = createCells(shape)
    if (cells.length > 0) {
      cell.current = cells[0]
    }
    const str = getSVGNode(graph, cells)
    // 显示节点
    setHtml(str)
    // 注册拖放事件
    const editorGraph = EditorExecutor.graph
    const dragElt = document.createElement('div')
    dragElt.style.border = 'dashed black 1px'
    dragElt.style.width = `${shape.width}px`
    dragElt.style.height = `${shape.height}px`

    mxUtils.makeDraggable(
      //eslint-disable-line
      //eslint-disable-line
      dom.current,
      graphF,
      dropSuc,
      dragElt,
      null,
      null,
      editorGraph.autoScroll,
      true
    )
  }, [])

  /**
   * 拖放成功的回调
   * @param graph2
   * @param evt
   * @param target
   * @param x
   * @param y
   */
  const dropSuc = (graph2, evt, target, x, y) => {
    //成功再次放置一个cell
    console.log(props.shape.name)
    graph2.importCells([cell.current], x, y, target)
  }

  const graphF = (evt) => {
    const editorGraph = EditorExecutor.graph
    const x = mxEvent.getClientX(evt) //eslint-disable-line
    const y = mxEvent.getClientY(evt) //eslint-disable-line
    const elt = document.elementFromPoint(x, y)

    if (mxUtils.isAncestorNode(editorGraph.container, elt)) {
      //eslint-disable-line
      //eslint-disable-line
      return editorGraph
    }

    return null
  }
  return (
    <a
      ref={dom}
      key={`panel_a_${shape.name}`}
      className="geItem custom-sidebar-node common-panel-node"
    >
      <Tooltip placement="top" title={shape.label} key={`panel_${shape.name}`} className="tooltip">
        <span
          dangerouslySetInnerHTML={{
            __html: html
          }}
        ></span>
        <span className="sidebar-node-label">{shape.label}</span>
      </Tooltip>
    </a>
  )
}
